package com.zg.autoform.web;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.zg.autoform.web.req.AddViewReq;
import com.zg.autoform.web.req.UpdateViewLayoutReq;
import com.zg.autoform.web.req.UpdateViewReq;
import com.zg.common.core.A;
import com.zg.common.core.R;
import com.zg.common.core.dao.BaseEntity;
import com.zg.common.core.dao.autoform.*;
import com.zg.common.core.dao.system.SysConfig;
import com.zg.common.core.dao.system.SysConfigDao;
import com.zg.common.core.dao.system.SysDict;
import com.zg.common.core.dao.system.SysDictDao;
import com.zg.common.core.util.JsonUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * @author Zxb
 */
@RestController
@RequiredArgsConstructor
@Api(tags = {"zxb视图功能"})
public class ZxbViewController {
    private final DiyViewDao viewDao;
    private final DiyLayoutDao layoutDao;
    private final DiyColumnDao columnDao;
    private final DiyFormDao formDao;
    private final SysDictDao dictDao;

    @ApiOperation("查询视图基本信息")
    @GetMapping("/zxb/view/info")
    public R findInfo(Long id) {
        DiyView view = viewDao.getById(id);
        return R.success(view);
    }

    @ApiOperation("查询视图布局和字段信息")
    @GetMapping("/zxb/view/findById")
    public R findById(Long id) {
        DiyView view = viewDao.getById(id);
        List<DiyLayout> layoutList = layoutDao.list(
                new LambdaQueryWrapper<DiyLayout>()
                        .eq(DiyLayout::getViewId, id));
        ObjectNode result = JsonUtil.on();
        ArrayNode an = JsonUtil.an();
        layoutList.stream().forEach(layout -> {
            DiyColumn column = columnDao.getById(layout.getColumnId());
            ObjectNode on = JsonUtil.on();
            on.put("id", column.getId().toString());
            on.put("name", column.getName());
            on.put("code", column.getCode());
            on.put("compType", column.getCompType());
            on.put("isNeed", column.getIsNeed());
            on.put("offset", layout.getOffset());
            on.put("layoutId", layout.getId().toString());
            on.put("span", layout.getSpan());
            on.put("divider", layout.getDivider());
            on.put("unit", layout.getUnit());
            on.put("showLabel",layout.getShowLabel());
            on.put("showVal",layout.getShowVal());
            on.put("isHide",layout.getIsHide());
            on.put("defaultVal", column.getDefaultVal());
            on.put("extra", column.getExtra());
            on.put("sort", layout.getSort());
            an.add(on);
        });
        result.put("name", view.getName());
        result.put("type", view.getType());
        result.put("showTitle", view.getShowTitle());
        result.put("title", view.getTitle());
        result.put("layout", view.getLayout());
        result.put("columns", an);
        return R.success(result);
    }

    @GetMapping("/zxb/view/list")
    public R list(Long formId) {
        List<DiyView> list = viewDao.list(
                new LambdaQueryWrapper<DiyView>()
                        .eq(DiyView::getFormId, formId)
                        .orderByDesc(BaseEntity::getCreateTime));
        if(CollUtil.isEmpty(list)){
            //根据配置新建视图
            String key = "viewType";
            SysDict dict = dictDao.getOne(
                    new LambdaQueryWrapper<SysDict>()
                            .eq(SysDict::getCode, key)
            );
            A.isInDatabase(dict, "视图类型字典");
            List<SysDict> optionList = dictDao.list(
                    new LambdaQueryWrapper<SysDict>()
                            .eq(SysDict::getPid, dict.getId())
            );
            if(CollUtil.isEmpty(optionList)){
                return R.error("请配置视图类型");
            }
            List<DiyView> addList = new ArrayList<>();
            optionList.stream().forEach(t->{
                DiyView obj = new DiyView();
                obj.setFormId(formId);
                obj.setName(t.getName());
                obj.setType(t.getCode());
                obj.setLayout("{\"视图边距\":10,\"标签宽度\":120,\"标签对齐\":\"right\",\"左右间距\":10,\"上下间距\":10}");
                obj.setShowTitle(false);
                addList.add(obj);
            });
            viewDao.saveBatch(addList);
            return R.success(addList);
        }
        return R.success(list);
    }

    @PostMapping("/zxb/view/del")
    public R del(@RequestBody List<Long> ids) {
        viewDao.removeBatchByIds(ids);
        return R.success();
    }


    @PostMapping("/zxb/view/add")
    public R add(@RequestBody AddViewReq req) {
        if(viewDao.exists(new LambdaQueryWrapper<DiyView>()
                .eq(DiyView::getFormId, req.getFormId())
                .eq(DiyView::getName, req.getName()))){
            return R.error("该视图名称已存在");
        }
        DiyView view = new DiyView();
        BeanUtil.copyProperties(req,view);
        viewDao.save(view);
        return R.success();
    }

    @PostMapping("/zxb/view/update")
    public R update(@RequestBody UpdateViewReq req) {
        DiyView old = viewDao.getById(req.getId());
        if(viewDao.exists(new LambdaQueryWrapper<DiyView>()
                .ne(DiyView::getId, old.getId())
                .eq(DiyView::getFormId, old.getFormId())
                .eq(DiyView::getName, req.getName()))){
            return R.error("视图名称已存在");
        }
        old.setType(req.getType());
        old.setTitle(req.getTitle());
        old.setShowTitle(req.getShowTitle());
        viewDao.updateById(old);
        return R.success();
    }

    @GetMapping("/zxb/view/listAllColumn")
    public R listAllColumn(Long viewId) {
        DiyView view = viewDao.getById(viewId);
        A.isInDatabase(view, "视图");
        DiyForm form = formDao.getById(view.getFormId());
        A.isInDatabase(form, "表单");
        List<DiyColumn> columnList = columnDao.list(
                new LambdaQueryWrapper<DiyColumn>()
                        .eq(DiyColumn::getFormId, form.getId()));
        return R.success(columnList);
    }

    @PostMapping("/zxb/view/updateLayout")
    @Transactional(rollbackFor = Exception.class)
    public R updateLayout(@RequestBody UpdateViewLayoutReq req) {
        //更新视图的布局参数
        DiyView view = viewDao.getById(req.getViewId());
        view.setLayout(req.getLayout());
        viewDao.updateById(view);
        //删除视图所有字段
        layoutDao.remove(new LambdaQueryWrapper<DiyLayout>()
                .eq(DiyLayout::getViewId, req.getViewId()));
        //批量保存视图所有字段
        List<DiyLayout> layoutList = req.getColumnList().stream().map(column -> {
            DiyLayout layout = new DiyLayout();
            layout.setColumnId(column.getColumnId());
            layout.setColumnCode(column.getColumnCode());
            layout.setColumnType(column.getColumnType());
            layout.setSpan(column.getSpan());
            layout.setOffset(column.getOffset());
            layout.setSort(column.getSort());
            layout.setViewId(view.getId());
            layout.setFormId(view.getFormId());
            layout.setIsHide(false);
            layout.setShowLabel(true);
            layout.setShowVal(false);
            return layout;
        }).collect(Collectors.toList());
        layoutDao.saveBatch(layoutList);
        return R.success();
    }

    @PostMapping("/zxb/view/sortColumn")
    public R sortColumn(@RequestBody List<String> list) {
        AtomicInteger count = new AtomicInteger();
        list.stream().forEach(t -> {
            String[] arr = t.split(":");
            Long columnId = Long.valueOf(arr[0]);
            Long viewId = Long.valueOf(arr[1]);
            Integer sort = Integer.valueOf(arr[2]);
            DiyColumn column = columnDao.getById(columnId);
            DiyLayout layout = layoutDao.getOne(new QueryWrapper<DiyLayout>()
                    .lambda()
                    .eq(DiyLayout::getViewId, viewId)
                    .eq(DiyLayout::getColumnId, columnId));
            if (layout == null) {
                layout = new DiyLayout();
                layout.setFormId(column.getFormId());
                layout.setViewId(viewId);
                layout.setColumnId(columnId);
                layout.setColumnCode(column.getCode());
                layout.setColumnType(column.getCompType());
                layout.setSort(sort);
                layout.setOffset(0);
                layout.setSpan(12);
                layoutDao.save(layout);
            } else {
                layout.setSort(sort);
                layoutDao.updateById(layout);
            }
            count.getAndIncrement();
        });
        return R.success(count.get());
    }
}
